/*******************************************************************************
 *  Copyright (c) [scl]。保留所有权利。
 *     本文仅供个人学习和研究使用，禁止用于商业用途。
 ******************************************************************************/

#ifndef STM32_LIB_MODBUS_SLAVE_H
#define STM32_LIB_MODBUS_SLAVE_H

#include "sys_core.h"
#include "modbus_common.h"


typedef enum {
    rtu_mode, /*RTU 模式*/
    tcp_mode,/*TCP 模式*/

} md_slave_mode_def; /*从机模式定义*/
typedef enum {
    rsp_ok = 0x0,
    // 不支持的功能码
    rsp_nut_support_cmd = 0x1,
    // 寄存器地址错误
    rsp_err_reg_addr = 0x2,
    // 数据值域错误
    rsp_err_value = 0x3,
    // 写入失败
    rsp_err_write = 0x4,
} slave_rsp_code_def;
typedef struct {
    uint8_t slave_addr;
    uint8_t func_code;
    uint16_t reg_addr;
    uint16_t reg_num;
    uint8_t *data;
    uint16_t data_len;
} mb_slave_parse_data_t; /*modbus从机解析数据结构体定义*/
/**
 * @brief 获取从机地址
 * @return
 */
extern uint8_t mb_slave_get_addr(void);

/**
 * @brief 从机响应数据
 * @param data
 * @param len
 */
extern void mb_send(void *data, uint16_t len);
/**
 * @brief 从机接收数据
 * @param ret_len 保存接收数据的长度
 * @return 返回接收数据首地址，如果没有接收数据则返回NULL
 */
extern uint8_t *mb_slave_read_rec_data(uint16_t *ret_len);

/**
 * @brief 获取从机响应数据存储的首地址
 * @return
 */
extern uint8_t *mb_slave_get_response_buf(void);

/*读线圈状态*/
extern slave_rsp_code_def slave_read_coil_state(uint16_t reg_addr, uint16_t reg_num, bool *ret_data);

/*读输入状态*/
extern slave_rsp_code_def slave_read_input_state(uint16_t reg_addr, uint16_t reg_num, bool *ret_data);

/*读保持寄存器*/
extern slave_rsp_code_def slave_read_hold_reg(uint16_t reg_addr, uint16_t reg_num, uint8_t *ret_data);

/*读输入寄存器*/
extern slave_rsp_code_def slave_read_input_reg(uint16_t reg_addr, uint16_t reg_num, uint8_t *ret_data);

extern slave_rsp_code_def slave_write_one_reg(uint16_t reg_addr, uint16_t data);

extern slave_rsp_code_def slave_write_mul_coils_reg(uint16_t reg_addr, uint16_t reg_num, bool *data);

extern slave_rsp_code_def slave_write_mul_reg(uint16_t reg_addr, uint16_t reg_num, uint8_t *data);

extern slave_rsp_code_def slave_write_one_coil(uint16_t reg_addr, bool val);
/*************************************************外部回调注册***************************************************/
/**
 * @brief 设置从机当前配置模式
 * @param mode
 */
void mb_slave_set_cur_mode(md_slave_mode_def mode);

void mb_slave_set_debug_call(fn_debug_log_def_t debug_call);

/**
 * @brief modbus从机入口函数
 */
void modbus_poll(void);

/**
 * @brief modbus从机入口函数，数据源来自外部
 */
void modbus_poll_rec(uint8_t *data, uint16_t len);

#endif //STM32_LIB_MODBUS_SLAVE_H
